package com.example.shutdown_v1.config;

import lombok.extern.slf4j.Slf4j;
import org.eclipse.paho.client.mqttv3.MqttConnectOptions;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.integration.channel.DirectChannel;
import org.springframework.integration.core.MessageProducer;
import org.springframework.integration.mqtt.core.DefaultMqttPahoClientFactory;
import org.springframework.integration.mqtt.core.MqttPahoClientFactory;
import org.springframework.integration.mqtt.inbound.MqttPahoMessageDrivenChannelAdapter;
import org.springframework.integration.mqtt.outbound.MqttPahoMessageHandler;
import org.springframework.integration.mqtt.support.DefaultPahoMessageConverter;
import org.springframework.messaging.MessageChannel;
import org.springframework.integration.annotation.ServiceActivator;

/**
 * MQTT配置类
 */
@Slf4j
@Configuration
public class MqttConfig {
    
    @Value("${mqtt.broker.url}")
    private String brokerUrl;
    
    @Value("${mqtt.broker.username:}")
    private String username;
    
    @Value("${mqtt.broker.password:}")
    private String password;
    
    @Value("${mqtt.client.id}")
    private String clientId;
    
    @Value("${mqtt.topics}")
    private String topics;  // 支持多个主题，逗号分隔或通配符
    
    @Value("${mqtt.qos}")
    private int qos;
    
    /**
     * MQTT客户端工厂
     */
    @Bean
    public MqttPahoClientFactory mqttClientFactory() {
        DefaultMqttPahoClientFactory factory = new DefaultMqttPahoClientFactory();
        MqttConnectOptions options = new MqttConnectOptions();
        
        options.setServerURIs(new String[]{brokerUrl});
        
        // 只有配置了用户名密码才设置认证信息
        if (username != null && !username.trim().isEmpty()) {
            options.setUserName(username);
        }
        if (password != null && !password.trim().isEmpty()) {
            options.setPassword(password.toCharArray());
        }
        options.setCleanSession(false);  // 改为false，保留会话，避免离线时消息丢失
        options.setKeepAliveInterval(60);
        options.setConnectionTimeout(30);
        options.setAutomaticReconnect(true);
        
        // 【重要】设置最大消息大小 (默认32KB,这里设置为256KB以支持大数据包)
        options.setMaxInflight(1000);  // 允许同时传输的最大消息数
        // 注意: MQTT协议本身的最大包大小是256MB,但broker可能有限制
        
        factory.setConnectionOptions(options);
        
        log.info("MQTT客户端工厂初始化完成: {} (CleanSession=false, 保留会话)", brokerUrl);
        return factory;
    }
    
    /**
     * MQTT输入消息通道
     */
    @Bean
    public MessageChannel mqttInputChannel() {
        return new DirectChannel();
    }
    
    /**
     * MQTT消息接收适配器（支持多主题订阅）
     */
    @Bean
    public MessageProducer inbound() {
        String[] topicArray;
        if (topics.contains(",")) {
            topicArray = topics.split(",");
            for (int i = 0; i < topicArray.length; i++) {
                topicArray[i] = topicArray[i].trim();
            }
        } else {
            topicArray = new String[]{topics};
        }
        
        MqttPahoMessageDrivenChannelAdapter adapter =
                new MqttPahoMessageDrivenChannelAdapter(clientId, mqttClientFactory(), topicArray);
        
        adapter.setCompletionTimeout(5000);
        DefaultPahoMessageConverter converter = new DefaultPahoMessageConverter();
        converter.setPayloadAsBytes(true);  //  接收字节数组，避免二进制数据被错误解码
        adapter.setConverter(converter);
        
        adapter.setQos(qos);
        adapter.setOutputChannel(mqttInputChannel());
        
        log.info("MQTT消息适配器初始化完成 - 订阅主题: {}, QoS: {}, 字节数组模式: true", String.join(",", topicArray), qos);
        return adapter;
    }
    
    /**
     * MQTT输出消息通道（用于发送指令）
     */
    @Bean
    public MessageChannel mqttOutboundChannel() {
        return new DirectChannel();
    }
    
    /**
     * MQTT消息发送处理器（用于发送电力设备查询指令）
     */
    @Bean
    @ServiceActivator(inputChannel = "mqttOutboundChannel")
    public MqttPahoMessageHandler mqttOutbound() {
        MqttPahoMessageHandler messageHandler = new MqttPahoMessageHandler(
                clientId + "_out", mqttClientFactory());
        messageHandler.setAsync(true);
        messageHandler.setDefaultTopic("/mallpower/get");  // 当前版本默认主题
        messageHandler.setDefaultRetained(false);
        messageHandler.setDefaultQos(qos);
        
        log.info("MQTT消息发送处理器初始化完成 - 默认主题: /mallpower/get, QoS: {}", qos);
        return messageHandler;
    }
    
}

